﻿// Decompiled with JetBrains decompiler
// Type: DnProcessSimulateCommands.TcCommands.CApAWCSearchMFGConnectionManager
// Assembly: DnProcessSimulateCommands, Version=2402.0.0.890, Culture=neutral, PublicKeyToken=null
// MVID: A885D881-AEDF-447E-852A-6F13102E089C
// Assembly location: C:\Program Files\Tecnomatix_2402\eMPower\DotNetCommands\DnProcessSimulateCommands.dll

using ActiveWorkspaceHosting;
using EngineeringInternalExtension;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows.Input;
using Tecnomatix.Engineering;
using Tecnomatix.Planning;


namespace DnProcessSimulateCommands.TcCommands;

internal class CApAWCSearchMFGConnectionManager : CApAWCHostSessionManager
{
  private const string CLS_FUNCTION_NAME = "PSHostedSearchMfg";
  private const string REG_ENTRY_DEBUG_FULL_AWC_URL = "SearchMfgAddress Debug";
  private const string BOM_PREFIX = "BOM::";
  private Cursor m_currentCursor;
  private CApAWCMfgTcServices m_mfgServices;
  private bool m_SelectionSynchronizationSupported;
  private bool m_SelectionSynchronizationSupportedInitialized;
  private bool m_isPreviewOn;
  private ITxObject m_targetOperation;

  public CApAWCSearchMFGConnectionManager() => this.m_mfgServices = new CApAWCMfgTcServices();

  public event EventHandler<CApAWCMfgsLoadedEventArgs> MfgsLoaded;

  public event EventHandler<CApAWCSelectMfgsInPSEventArgs> SelectMfgsInPS;

  public override string DebugEntry => "SearchMfgAddress Debug";

  public override string ComponentId => "PSHostedSearchMfg";

  internal bool GetIsMFGSearchProvidedByAw(TxAWSConnectionManagerEx connectionManager)
  {
    Tuple<uint, uint, uint> awVersion = connectionManager.GetAwVersion();
    return awVersion.Item1 > 6U || awVersion.Item1 == 6U && awVersion.Item2 >= 2U || awVersion.Item1 == 6U && awVersion.Item2 == 1U && awVersion.Item3 >= 3U;
  }

  public override string GetComponentUrlSuffix(TxAWSConnectionManagerEx connectionManager)
  {
    string componentUrlSuffix = (string) null;
    if (this.GetIsMFGSearchProvidedByAw(connectionManager))
      componentUrlSuffix = "?ah=true#/tcmaMfgSearch?";
    return componentUrlSuffix;
  }

  public ITxObject TargetOperation
  {
    get => this.m_targetOperation;
    set
    {
      switch (value)
      {
        case ITxTcOperation _:
        case TxTcProcess _:
          this.m_targetOperation = value;
          break;
      }
    }
  }

  public bool SelectionSynchronizationSupported
  {
    get => this.m_SelectionSynchronizationSupported;
    set
    {
      if (this.m_SelectionSynchronizationSupportedInitialized)
        return;
      this.m_SelectionSynchronizationSupported = value;
      this.m_SelectionSynchronizationSupportedInitialized = true;
    }
  }

  public CApAWCMfgCache MfgCache => this.m_mfgServices.m_mfgCache;

  protected override void RegisterServicesInternal()
  {
    TxActiveWorkspaceHostManagerEx.Instance.SelectedObjectsRequested += new EventHandler<TxSelectedObjectsRequestedEventArgs>(this.m_hostManager_SelectedObjectsRequested);
    TxActiveWorkspaceHostManagerEx.Instance.RegisterUniqueService((TxBaseHostingService) new TxClientRequestLoadedMfgsSvc(new Func<TxRequestLoadedMfgsMsg, TxRequestLoadedMfgsMsg>(this.LoadedMfgsRequestedHandler)));
    TxActiveWorkspaceHostManagerEx.Instance.RegisterUniqueService((TxBaseHostingService) new TxClientRequestLoadedMfgsWithStatesSvc(new Func<TxRequestLoadedMfgsInputMsg, TxRequestLoadedMfgsOutputMsg>(this.LoadedMfgsWithStatesRequestedHandler)));
    TxActiveWorkspaceHostManagerEx.Instance.RegisterUniqueService((TxBaseHostingService) new TxHostLoadMfgsSvc(new Action<TxHostLoadMfgsMsg>(this.LoadMfgsInPS)));
    TxActiveWorkspaceHostManagerEx.Instance.RegisterUniqueService((TxBaseHostingService) new TxHostPreviewMfgsSvc(new Action<TxHostPreviewMfgsMsg>(this.PreviewMfgsInPS)));
    TxActiveWorkspaceHostManagerEx.Instance.RegisterUniqueService((TxBaseHostingService) new TxHostSelectMfgsInProcessSimulateSvc(new Action<TxHostSelectMfgsInProcessSimulateMsg>(this.SelectMfgsInPSHandler)));
    TxActiveWorkspaceHostManagerEx.Instance.RegisterUniqueService((TxBaseHostingService) new TxHostUpdateMfgVisibilitySvc(new Action<TxHostUpdateMfgVisibilityMsg>(this.UpdateMfgVisibilityInPS)));
  }

  protected override void UnregisterServicesInternal()
  {
    TxActiveWorkspaceHostManagerEx.Instance.SelectedObjectsRequested -= new EventHandler<TxSelectedObjectsRequestedEventArgs>(this.m_hostManager_SelectedObjectsRequested);
    TxActiveWorkspaceHostManagerEx.Instance.UnregisterUniqueService((TxBaseHostingService) new TxClientRequestLoadedMfgsSvc(new Func<TxRequestLoadedMfgsMsg, TxRequestLoadedMfgsMsg>(this.LoadedMfgsRequestedHandler)));
    TxActiveWorkspaceHostManagerEx.Instance.UnregisterUniqueService((TxBaseHostingService) new TxClientRequestLoadedMfgsWithStatesSvc(new Func<TxRequestLoadedMfgsInputMsg, TxRequestLoadedMfgsOutputMsg>(this.LoadedMfgsWithStatesRequestedHandler)));
    TxActiveWorkspaceHostManagerEx.Instance.UnregisterUniqueService((TxBaseHostingService) new TxHostLoadMfgsSvc(new Action<TxHostLoadMfgsMsg>(this.LoadMfgsInPS)));
    TxActiveWorkspaceHostManagerEx.Instance.UnregisterUniqueService((TxBaseHostingService) new TxHostPreviewMfgsSvc(new Action<TxHostPreviewMfgsMsg>(this.PreviewMfgsInPS)));
    TxActiveWorkspaceHostManagerEx.Instance.UnregisterUniqueService((TxBaseHostingService) new TxHostSelectMfgsInProcessSimulateSvc(new Action<TxHostSelectMfgsInProcessSimulateMsg>(this.SelectMfgsInPSHandler)));
    TxActiveWorkspaceHostManagerEx.Instance.UnregisterUniqueService((TxBaseHostingService) new TxHostUpdateMfgVisibilitySvc(new Action<TxHostUpdateMfgVisibilityMsg>(this.UpdateMfgVisibilityInPS)));
  }

  protected override List<KeyValuePair<string, string>> GetUriAttributes()
  {
    List<KeyValuePair<string, string>> uriAttributes = new List<KeyValuePair<string, string>>();
    string productWindowTag = this.GetProductWindowTag();
    string processWindowTag = this.GetProcessWindowTag();
    if (!string.IsNullOrEmpty(productWindowTag) && !string.IsNullOrEmpty(processWindowTag))
    {
      uriAttributes.Add(new KeyValuePair<string, string>("productUID", "BOM::" + productWindowTag));
      uriAttributes.Add(new KeyValuePair<string, string>("processUID", "BOM::" + processWindowTag));
    }
    return uriAttributes;
  }

  private string GetProductWindowTag()
  {
    string productWindowTag = (string) null;
    List<Tuple<string, string, string, string, string, string>> productScopes = TxTcSessionInfoEx.ProductScopes;
    string str;
    if (productScopes.Count == 1)
    {
      productWindowTag = productScopes[0].Item1;
      str = "Took the sole available.";
    }
    else if (productScopes.Count > 1)
    {
      List<string> suitableTopItemTypes = TxTcUtilities.GetPreference("User", "MEDynamicIPARootItemTypes").Where<string>((Func<string, bool>) (t => !string.IsNullOrEmpty(t))).ToList<string>();
      if (suitableTopItemTypes.Any<string>())
      {
        List<Tuple<string, string, string, string, string, string>> list = productScopes.Where<Tuple<string, string, string, string, string, string>>((Func<Tuple<string, string, string, string, string, string>, bool>) (view => IsSuitableTopRevisionType(view.Item6))).ToList<Tuple<string, string, string, string, string, string>>();
        if (list.Any<Tuple<string, string, string, string, string, string>>())
        {
          productWindowTag = list.ElementAt<Tuple<string, string, string, string, string, string>>(0).Item1;
          str = list.Count<Tuple<string, string, string, string, string, string>>() != 1 ? "Took one of multiple suitable." : "Took the sole suitable.";
        }
        else
        {
          productWindowTag = productScopes[0].Item1;
          str = "Took one of multiple available, because none of them matched the MEDynamicIPARootItemTypes preference.";
        }
      }
      else
      {
        productWindowTag = productScopes[0].Item1;
        str = "Took one of multiple available, because the MEDynamicIPARootItemTypes preference is not set.";
      }

      bool IsSuitableTopRevisionType(string revisionType)
      {
        TxPlanningTypeMetaData typeMetaData = TxApplication.ActiveDocument.PlatformGlobalServicesProvider.GetTypeMetaData(revisionType);
        return typeMetaData != null && suitableTopItemTypes.Contains(typeMetaData.ItemTypeName);
      }
    }
    else
      str = "None available.";
    if (!string.IsNullOrEmpty(str))
      TxApplication.LogWriter.WriteDetailedLine($"MFG Search: Product window: {str}");
    return productWindowTag;
  }

  private string GetProcessWindowTag()
  {
    string processWindowTag = (string) null;
    List<Tuple<string, string, string, string, string, string>> processScopes = TxTcSessionInfoEx.ProcessScopes;
    string str;
    if (processScopes.Count == 1)
    {
      processWindowTag = processScopes[0].Item1;
      str = "Took the sole available.";
    }
    else if (processScopes.Count > 1)
    {
      processWindowTag = processScopes[0].Item1;
      str = "Took one of multiple available!?";
    }
    else
      str = "None available!?";
    if (!string.IsNullOrEmpty(str))
      TxApplication.LogWriter.WriteDetailedLine($"MFG Search: Process window: {str}");
    return processWindowTag;
  }

  private void m_hostManager_SelectedObjectsRequested(
    object sender,
    TxSelectedObjectsRequestedEventArgs e)
  {
    Dictionary<ITxPlanningObject, string> bomLineUids = this.m_mfgServices.GetBomLineUids(TxApplication.ActiveSelection.GetFilteredItems((ITxTypeFilter) new CApMFGSearchTypeFilter()));
    List<string> stringList = new List<string>();
    if (bomLineUids != null)
      stringList.AddRange((IEnumerable<string>) bomLineUids.Values);
    e.SelectedIds = stringList;
  }

  private TxRequestLoadedMfgsMsg LoadedMfgsRequestedHandler(TxRequestLoadedMfgsMsg inputMessage)
  {
    this.ClearPreview();
    TxRequestLoadedMfgsMsg requestLoadedMfgsMsg = new TxRequestLoadedMfgsMsg();
    Dictionary<string, ITxPlanningObject> planningObjects = this.m_mfgServices.GetPlanningObjects(inputMessage.MfgIds);
    if (planningObjects != null && planningObjects.Count > 0)
    {
      List<string> list = planningObjects.Where<KeyValuePair<string, ITxPlanningObject>>((Func<KeyValuePair<string, ITxPlanningObject>, bool>) (p => p.Value != null && p.Value.EngineeringRepresentation != null)).Select<KeyValuePair<string, ITxPlanningObject>, string>((Func<KeyValuePair<string, ITxPlanningObject>, string>) (x => x.Key)).ToList<string>();
      requestLoadedMfgsMsg.MfgIds = list;
    }
    else
      requestLoadedMfgsMsg.MfgIds = new List<string>();
    return requestLoadedMfgsMsg;
  }

  private TxRequestLoadedMfgsOutputMsg LoadedMfgsWithStatesRequestedHandler(
    TxRequestLoadedMfgsInputMsg inputMessage)
  {
    TxRequestLoadedMfgsOutputMsg loadedMfgsOutputMsg = new TxRequestLoadedMfgsOutputMsg();
    loadedMfgsOutputMsg.MFGInfo = new List<TxLoadedMfgInfo>();
    this.ClearPreview();
    Dictionary<string, ITxPlanningObject> planningObjects = this.m_mfgServices.GetPlanningObjects(inputMessage.MfgIds);
    if (planningObjects != null && planningObjects.Count > 0)
      this.CollectLoadedMfgInfo(planningObjects, loadedMfgsOutputMsg.MFGInfo);
    return loadedMfgsOutputMsg;
  }

  private void CollectLoadedMfgInfo(
    Dictionary<string, ITxPlanningObject> bomLineDict,
    List<TxLoadedMfgInfo> loadedMfgInfo)
  {
    TxObjectList filteredItems = TxApplication.ActiveSelection.GetFilteredItems((ITxTypeFilter) new TxTypeFilter(typeof (TxMfgFeature)));
    foreach (string key in bomLineDict.Keys)
    {
      ITxPlanningObject itxPlanningObject = bomLineDict[key];
      if (itxPlanningObject != null && itxPlanningObject.EngineeringRepresentation != null)
      {
        TxMfgFeature engineeringRepresentation = itxPlanningObject.EngineeringRepresentation as TxMfgFeature;
        if (TxMfgFeature.op_Inequality(engineeringRepresentation, (ITxObject) null))
          loadedMfgInfo.Add(new TxLoadedMfgInfo()
          {
            UID = key,
            Visible = engineeringRepresentation.Visibility == 0,
            Selected = ((Collection<ITxObject>) filteredItems).Contains((ITxObject) engineeringRepresentation)
          });
      }
    }
  }

  private void LoadMfgsInPS(TxHostLoadMfgsMsg input)
  {
    if (this.m_isPreviewOn || this.SelectionSynchronizationSupported && this.MfgCache.HasPreviewdMfgs)
    {
      this.MfgCache.UpdateVisibilityInTCMABeforePreviewIsCleared(input.MFGInfo);
      this.ClearPreview();
    }
    this.LoadMfgs((IEnumerable<ITxMfgInfo>) input.MFGInfo, false);
  }

  private void PreviewMfgsInPS(TxHostPreviewMfgsMsg message)
  {
    bool showPreview = message.ShowPreview;
    if (showPreview || showPreview != this.m_isPreviewOn)
      this.ClearPreview();
    this.m_isPreviewOn = showPreview;
    if (!this.m_isPreviewOn)
      return;
    this.LoadMfgs((IEnumerable<ITxMfgInfo>) message.MFGInfo, true);
  }

  private void UpdateMfgVisibilityInPS(TxHostUpdateMfgVisibilityMsg message)
  {
    if (!this.SelectionSynchronizationSupported)
      return;
    this.LoadMfgs((IEnumerable<ITxMfgInfo>) message.MFGInfo, true);
  }

  private void LoadMfgs(IEnumerable<ITxMfgInfo> mfgsInfo, bool isPreview)
  {
    if (mfgsInfo == null || mfgsInfo.Count<ITxMfgInfo>() <= 0)
      return;
    bool isProcessOrOperationLoaded = CApAWCMfgTcServices.ProcessOrOperationContainerIsLoaded();
    TxTcImportResultEx result = (TxTcImportResultEx) null;
    IEnumerable<ITxMfgInfo> itxMfgInfos = mfgsInfo.Where<ITxMfgInfo>((Func<ITxMfgInfo, bool>) (x => x.UID != null));
    IEnumerable<string> strings = itxMfgInfos.Select<ITxMfgInfo, string>((Func<ITxMfgInfo, string>) (x => x.UID));
    if (!CApAssignmnetUtil.CanLoadMfgs(strings, this.TargetOperation, isPreview))
      return;
    this.SetWaitCursor();
    if (isProcessOrOperationLoaded)
      result = this.m_mfgServices.LoadMfgs(strings, isPreview, this.TargetOperation);
    CApAssignmnetUtil.CompleteMfgAssignment(result, this.TargetOperation, isPreview);
    this.RestoreCursor();
    this.OnMfgsLoaded(itxMfgInfos, result, isPreview, isProcessOrOperationLoaded);
  }

  private void OnMfgsLoaded(
    IEnumerable<ITxMfgInfo> mfgsToLoad,
    TxTcImportResultEx result,
    bool isPreview,
    bool isProcessOrOperationLoaded)
  {
    if (this.MfgsLoaded == null)
      return;
    this.MfgsLoaded((object) this, new CApAWCMfgsLoadedEventArgs()
    {
      MfgsToLoad = mfgsToLoad,
      Result = result,
      IsPreview = isPreview,
      IsProcessOrOperationLoaded = isProcessOrOperationLoaded
    });
  }

  private void GetPreviewedAndLoadedMfgsFromCurrentSelection(
    TxObjectList previewdMfgs,
    TxObjectList loadedMfgs)
  {
    foreach (ITxObject filteredItem in (Collection<ITxObject>) TxApplication.ActiveSelection.GetFilteredItems((ITxTypeFilter) new TxTypeFilter(typeof (TxMfgFeature))))
    {
      if (filteredItem.IsTransient)
        ((Collection<ITxObject>) previewdMfgs).Add(filteredItem);
      else
        ((Collection<ITxObject>) loadedMfgs).Add(filteredItem);
    }
  }

  public List<string> GetMfgsFromCurrentSelection()
  {
    TxObjectList txObjectList1 = new TxObjectList();
    TxObjectList txObjectList2 = new TxObjectList();
    this.GetPreviewedAndLoadedMfgsFromCurrentSelection(txObjectList1, txObjectList2);
    List<string> previewedMfgsBomLineUids = this.MfgCache.GetPreviewedMfgsBomLineUids(txObjectList1);
    if (((Collection<ITxObject>) txObjectList2).Count > 0)
    {
      Dictionary<ITxPlanningObject, string> bomLineUids = this.m_mfgServices.GetBomLineUids(txObjectList2);
      if (bomLineUids != null)
        previewedMfgsBomLineUids.AddRange((IEnumerable<string>) bomLineUids.Values);
    }
    return previewedMfgsBomLineUids;
  }

  public IEnumerable<ITxObject> GetMfgsSelectedInTCMA(
    IEnumerable<TxTcResultObjectDataEx> loadedMfgs,
    IEnumerable<ITxMfgInfo> updatedMfgs)
  {
    List<ITxObject> mfgsSelectedInTcma = new List<ITxObject>();
    try
    {
      Dictionary<string, TxMfgFeature> dictionary1 = loadedMfgs.ToDictionary<TxTcResultObjectDataEx, string, TxMfgFeature>((Func<TxTcResultObjectDataEx, string>) (di => di.Uid), (Func<TxTcResultObjectDataEx, TxMfgFeature>) (di => di.Object as TxMfgFeature));
      Dictionary<string, bool> dictionary2 = updatedMfgs.Cast<TxMfgVisibilityUpdateInfo>().ToDictionary<TxMfgVisibilityUpdateInfo, string, bool>((Func<TxMfgVisibilityUpdateInfo, string>) (di => di.UID), (Func<TxMfgVisibilityUpdateInfo, bool>) (di => di.Selected));
      foreach (string key in dictionary1.Keys)
      {
        TxMfgFeature txMfgFeature = dictionary1[key];
        if (TxMfgFeature.op_Inequality(txMfgFeature, (ITxObject) null) && dictionary2.ContainsKey(key) && dictionary2[key])
          mfgsSelectedInTcma.Add((ITxObject) txMfgFeature);
      }
    }
    catch (Exception ex)
    {
      TxApplication.LogWriter.WriteExceptionLine(ex);
    }
    return (IEnumerable<ITxObject>) mfgsSelectedInTcma;
  }

  private void SelectMfgsInPSHandler(TxHostSelectMfgsInProcessSimulateMsg message)
  {
    if (!this.SelectionSynchronizationSupported)
      return;
    List<ITxObject> selectedMfgs = new List<ITxObject>();
    Dictionary<string, ITxPlanningObject> planningObjects = this.m_mfgServices.GetPlanningObjects(message.MfgIds);
    if (planningObjects != null && planningObjects.Count > 0)
      selectedMfgs = ((IEnumerable<ITxObject>) planningObjects.Where<KeyValuePair<string, ITxPlanningObject>>((Func<KeyValuePair<string, ITxPlanningObject>, bool>) (p => p.Value != null && p.Value.EngineeringRepresentation != null)).Select<KeyValuePair<string, ITxPlanningObject>, ITxPlanningObject>((Func<KeyValuePair<string, ITxPlanningObject>, ITxPlanningObject>) (x => x.Value))).ToList<ITxObject>();
    this.OnSelectMfgsInPS((IEnumerable<ITxObject>) selectedMfgs);
  }

  private void OnSelectMfgsInPS(IEnumerable<ITxObject> selectedMfgs)
  {
    if (this.SelectMfgsInPS == null)
      return;
    this.SelectMfgsInPS((object) this, new CApAWCSelectMfgsInPSEventArgs()
    {
      MfgsToSelect = selectedMfgs
    });
  }

  public void UpdateVisibilityInPSAfterPreview(
    IEnumerable<TxTcResultObjectDataEx> existingMfgs,
    IEnumerable<ITxMfgInfo> updatedMfgs)
  {
    if (!this.SelectionSynchronizationSupported)
      return;
    this.MfgCache.IgnoreVisiblityChange = true;
    try
    {
      this.MfgCache.UpdateVisibilityInPSAfterPreview(existingMfgs, updatedMfgs);
    }
    catch (Exception ex)
    {
      TxApplication.LogWriter.WriteExceptionLine(ex);
    }
    finally
    {
      this.MfgCache.IgnoreVisiblityChange = false;
    }
  }

  public void UpdateVisibilityInTCMAAfterLoad(IEnumerable<TxTcResultObjectDataEx> loadedMfgs)
  {
    if (!this.SelectionSynchronizationSupported)
      return;
    this.MfgCache.UpdateVisibilityInTCMAAfterLoad(loadedMfgs);
  }

  public void CachePreviewedMfgsBomLineUids(IEnumerable<TxTcResultObjectDataEx> resultObjects)
  {
    if (!this.SelectionSynchronizationSupported)
      return;
    foreach (TxTcResultObjectDataEx resultObject in resultObjects)
      this.MfgCache.AddPreviewedMfgBomLineUid(resultObject);
  }

  public void CacheLoadedMfgs(IEnumerable<ITxObject> loadedMfgs)
  {
    if (!this.SelectionSynchronizationSupported)
      return;
    foreach (ITxObject loadedMfg in loadedMfgs)
    {
      TxMfgFeature mfg = loadedMfg as TxMfgFeature;
      if (TxMfgFeature.op_Inequality(mfg, (ITxObject) null))
        this.MfgCache.Add(mfg);
    }
  }

  internal void InitMfgCache()
  {
    if (!this.SelectionSynchronizationSupported)
      return;
    this.MfgCache.Initialize();
  }

  internal void ClearPreview() => this.m_mfgServices.ClearMfgsPreview();

  private void RestoreCursor() => Mouse.OverrideCursor = this.m_currentCursor;

  private void SetWaitCursor()
  {
    this.m_currentCursor = Mouse.OverrideCursor;
    Mouse.OverrideCursor = Cursors.Wait;
  }
}
